/**
 * 
 */
package com.ra.pay.weixin;

import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Formatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;
import org.springframework.stereotype.Service;

import com.espirit.eap.sa.LoginUser;
import com.espirit.eap.sa.LoginUserService;
import com.espirit.weixin.core.AccessToken;
import com.espirit.weixin.core.WeixinConfig;
import com.espirit.weixin.core.WeixinUtil;
import com.googlecode.cswish.annotation.Rest;
import com.googlecode.cswish.exception.ApplicationException;
import com.googlecode.cswish.security.SafeManager;
import com.googlecode.cswish.struts.ContextHolder;
import com.googlecode.cswish.struts.spring.GenericService;
import com.ra.external.WeixinService;
import com.ra.external.WeixinUserService;
import com.ra.landlord.LandlordUserService;
import com.ra.landlord.vo.OrderVO;
import com.ra.order.OrderUtil;
import com.ra.order.rental.RentalOrder;
import com.ra.order.rental.RentalOrderService;
import com.ra.weixin.WeixinUser;

/**
 * 微信支付 服务
 *
 * @author colin
 * @version 2014-10-24
 */
@Service
public class WeixinPay_bakService {

	private static final Log logger = LogFactory.getLog(WeixinPayUtil.class);
	
	@Resource
	private WeixinUtil weixinUtil;
	
	@Resource
	private GenericService genericService;
	
	@Resource
	WeixinService weixinService;
	
	@Resource
	private LoginUserService loginUserService;
	
	@Resource
	private RentalOrderService rentalOrderService;
	
	@Resource
	private WeixinUserService weixinUserService;
	
	@Resource
	private SafeManager safeManager;
	
	/**
	 * 微信支付
	 * （接口：ra/pay/weixin/weixinPay.wxPay.html?goods.body=怡宝桶装水&goods.totalFee=1&goods.outTradeNo=11&openid=xxx）
	 * @param goods
	 * @param openid
	 * @return
	 * @throws ApplicationException
	 */
	public Map<String, String> wxPay(WeixinGoods goods, String openid){
		
		Map<String, String> map = new HashMap<String, String>();
		
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		
		map = jsApiPay(request, response, weixinConfig, goods, openid);
		return map;
	}
	
	/**
	 * 微信支付
	 * （接口：ra/pay/weixin/weixinPay.wxPay.html?goods.body=怡宝桶装水&goods.totalFee=1&goods.outTradeNo=11&openid=xxx）
	 * @param goods
	 * @param openid
	 * @return
	 * @throws ApplicationException
	 */
	public OrderVO wxPayNew(){
		// 获取最新的订单
		OrderVO orderVO = rentalOrderService.searchMyOrderVO();
		if (orderVO == null) {
			return null;
		}
		
		// 获取openid
		String openid = "";
		LoginUser loginUser =  loginUserService.getLoginUser();
		if(loginUser != null){
			WeixinUser model = new WeixinUser();
			model.setLoginUser(loginUser);
			List<WeixinUser> weixinUsers = genericService.searchAll(model).getData();
			if (CollectionUtils.isNotEmpty(weixinUsers)) {
				for (WeixinUser weixinUser : weixinUsers) {
					if (StringUtils.isNotBlank(weixinUser.getOpenid())) {
						openid = weixinUser.getOpenid();
						break;
					}
				}
			}
		}
		
		//ra/pay/weixin/weixinPay.wxPay.html?goods.body=怡宝桶装水&goods.totalFee=1&goods.outTradeNo=11&openid=xxx
		
		// 组装支付数据WeixinGoods
		WeixinGoods goods = new WeixinGoods();
		goods.setBody(orderVO.getOrderName());
		String totalFee = "0.00";
		if (orderVO.getTotalFee() != null) {
			totalFee = orderVO.getTotalFee().toString();
		}
		goods.setTotalFee(totalFee);
		goods.setOutTradeNo(orderVO.getOutTradeNo());
		
		System.out.println("-------------------------------");
		System.out.println("goods.body="+goods.getBody()+"   goods.setTotalFee="+goods.getTotalFee()+"   goods.OutTradeNo="+goods.getOutTradeNo());
		System.out.println("-------------------------------");
		
		Map<String, String> map = new HashMap<String, String>();
		
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		
		map = jsApiPay(request, response, weixinConfig, goods, openid);
		
		orderVO.setWxData(map);
		
		return orderVO;
	}
	
	/**
	 * test
	 * @param goods
	 * @param openid
	 * @return
	 * @throws ApplicationException
	 */
	public Map<String, String> wxPayNewRecharge(String totalFee, String openid){
		// 获取最新的订单
		
		//ra/pay/weixin/weixinPay.wxPay.html?goods.body=怡宝桶装水&goods.totalFee=1&goods.outTradeNo=11&openid=xxx
		
		// 组装支付数据WeixinGoods
		WeixinGoods goods = new WeixinGoods();
		goods.setBody("充值");
		goods.setTotalFee(totalFee);
		goods.setOutTradeNo("RECHARGE_"+OrderUtil.getOrderNum());
		
		logger.info("-------------------------------");
		logger.info("goods.body="+goods.getBody()+"   goods.setTotalFee="+goods.getTotalFee()+"   goods.OutTradeNo="+goods.getOutTradeNo());
		logger.info("-------------------------------");
		
		Map<String, String> map = new HashMap<String, String>();
		
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		
		String code = request.getParameter("code");
		System.out.println("==========code===========" + code);
		
		map = jsApiPay(request, response, weixinConfig, goods, openid);
		return map;
	}
	
	/**
	 * test
	 * ra/pay/weixin/weixinPay.wxPayNewOrder.html?goods.body=订单描述&goods.totalFee=1&goods.outTradeNo=ORDER_20151202233542336
	 * @param goods
	 * @param openid
	 * @return
	 * @throws ApplicationException
	 */
	@Rest(simpleServiceName = "anonymity", type = "free")
	public Map<String, String> wxPayNewOrder(WeixinGoods goods){

		logger.info("-------------------------------");
		logger.info("goods.body="+goods.getBody()+"   goods.setTotalFee="+goods.getTotalFee()+"   goods.OutTradeNo="+goods.getOutTradeNo());
		logger.info("-------------------------------");
		
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		
		String code = request.getParameter("code");
		System.out.println("==========code===========" + code);
		String openid = weixinUtil.getOpenidByToken(weixinConfig.getAppId(), weixinConfig.getSecret(), code);
		
		//登录
		LoginUser loginUser = weixinUserService.getLoginUserByOpenid(openid);
		request.setAttribute(LandlordUserService.REQ_FROM_WEIXIN, Boolean.TRUE);
		safeManager.login(request, loginUser.getLoginId(), ContextHolder.get().getSiteName());
		
		//新增订单
		
		
		
		
		Map<String, String> map = new HashMap<String, String>();
		map = jsApiPay(request, response, weixinConfig, goods, openid);
		return map;
	}
	
	/**
	 * 微信企业转账
	 * @param transfer
	 * @return
	 */
	public String wxTransfer(EnterpriseTransfer transfer){
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse response = ServletActionContext.getResponse();
		
		return WeixinPayUtil.enterprisePay(request, response, weixinConfig, transfer);
	}
	
	@SuppressWarnings("static-access")
	public Map<String,String> jsApiPay(HttpServletRequest req,HttpServletResponse res,WeixinConfig weixinConfig,WeixinGoods goods, String openid){
		Map<String, String> map = new HashMap<String, String>();
		//网页授权后获取传递的参数
		String body = goods.getBody(); 	//商品描述
		String orderNo = goods.getOutTradeNo(); 
		String money = goods.getTotalFee();
		
		//金额转化为分为单位
		String finalmoney = BigDecimal.valueOf(Double.parseDouble(money)).multiply(new BigDecimal(100)).toString(); 
		
		
		//商户相关资料 
	    String appid = weixinConfig.getAppId();
	    String appsecret = weixinConfig.getSecret();
	    String partner = weixinConfig.getPartnerId();
	    String partnerkey = weixinConfig.getPartnerKey();
	    
	    if (logger.isDebugEnabled()) {
			logger.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
			logger.debug("appid:" + appid+"\n");
			logger.debug("appsecret:" + appsecret+"\n");
			logger.debug("partner:" + partner+"\n");
			logger.debug("partnerkey:" + partnerkey+"\n");
			logger.debug("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
		}
	    
	    //这里notify_url是 支付完成后微信发给该链接信息，可以判断会员是否支付成功，改变订单状态等。
		String notify_url = weixinConfig.getNotifyUrl();
		
		//获取openId后调用统一支付接口https://api.mch.weixin.qq.com/pay/unifiedorder
		//商户号
		String mch_id = partner;
		//子商户号  非必输
		//String sub_mch_id="";
		//设备号   非必输
		String device_info="";
		//随机数 
		String nonce_str = WeixinPayUtil.getRandomNum();
		
		//附加数据(比如备注)
		String attach = "";
		
		//商户订单号，不允许重复，追加：_毫秒
		String out_trade_no = orderNo;
		
		int intMoney = Integer.parseInt(finalmoney.split("\\.")[0]);
		
		//总金额以分为单位，不带小数点
		finalmoney = String.valueOf(intMoney);
		//订单生成的机器 IP
		String spbill_create_ip = req.getRemoteAddr();
		//订单生成时间   非必输
		//String time_start ="";
		//订单失效时间      非必输
		//String time_expire = "";
		//商品标记   非必输
		//String goods_tag = "";
		
		String trade_type = "JSAPI";
		//非必输
		//String product_id = "";
		SortedMap<String, String> packageParams = new TreeMap<String, String>();
		packageParams.put("appid", appid);  
		packageParams.put("mch_id", mch_id);  
		packageParams.put("nonce_str", nonce_str);  
		packageParams.put("body", body);  
		packageParams.put("attach", attach);  
		packageParams.put("out_trade_no", out_trade_no);  
	    
		//这里写的金额为1 分到时修改
		//packageParams.put("total_fee", "1");
		packageParams.put("total_fee", finalmoney);
		packageParams.put("spbill_create_ip", spbill_create_ip);  
		packageParams.put("notify_url", notify_url);  
		packageParams.put("trade_type", trade_type);  
		packageParams.put("openid", openid);  
		
		//增加业务ID
		if(goods.getBusinessId() != null) {
			packageParams.put("business_id", goods.getBusinessId().toString());
		}
		
		RequestHandler reqHandler = new RequestHandler(req, res);
		reqHandler.init(appid, appsecret, partnerkey);
		
		String sign = reqHandler.createSign(packageParams);
		String xml="<xml>"+
				"<appid>"+appid+"</appid>"+
				"<mch_id>"+mch_id+"</mch_id>"+
				"<nonce_str>"+nonce_str+"</nonce_str>"+
				"<sign>"+sign+"</sign>"+
				"<body><![CDATA["+body+"]]></body>"+
				"<attach>"+attach+"</attach>"+
				"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
				//金额，这里写的1 分到时修改
				//"<total_fee>"+1+"</total_fee>"+
				"<total_fee>"+finalmoney+"</total_fee>"+
				"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
				"<notify_url>"+notify_url+"</notify_url>"+
				"<trade_type>"+trade_type+"</trade_type>"+
				"<openid>"+openid+"</openid>"+
				"</xml>";
		System.out.println(xml);
		String allParameters = "";
		try {
			allParameters =  reqHandler.genPackage(packageParams);
		} catch (Exception e) {
			logger.error("获取package的签名包出现异常",e);
		}
		String createOrderURL = "https://api.mch.weixin.qq.com/pay/unifiedorder";
		String prepay_id="";
		try {
			// 根据订单编号查询对应订单
//			RentalOrder queryModel = new RentalOrder();
//			queryModel.setOutTradeNo(orderNo);
//			RentalOrder rentalOrder = genericService.searchAll(queryModel).getData(0);
			prepay_id = new GetWxOrderno().getPayNo(createOrderURL, xml);
//			if(StringUtils.isBlank(prepay_id)){
//				if(StringUtils.isNotBlank(rentalOrder.getPrepayId()) && 
//						rentalOrder.getOrderState() == RentalOrder.ORDER_STATE_WAITING_PAYMENT) {
//					prepay_id = rentalOrder.getPrepayId();
//				} 
//			} else {
//				rentalOrder.setPrepayId(prepay_id);
//				genericService.update(rentalOrder);
//			}
			
			if(StringUtils.isBlank(prepay_id)) {
				req.setAttribute("ErrorMsg", "统一支付接口获取预支付订单出错");
				res.sendRedirect("error.jsp");
			}
		} catch (Exception e1) {
			logger.error("获取微信支付prepay_id出错", e1);
		}
		SortedMap<String, String> finalpackage = new TreeMap<String, String>();
		String appid2 = appid;
		String timestamp = Sha1Util.getTimeStamp();
		String nonceStr2 = nonce_str;
		String prepay_id2 = "prepay_id="+prepay_id;
		String packages = prepay_id2;
		finalpackage.put("appId", appid2);  
		finalpackage.put("timeStamp", timestamp);  
		finalpackage.put("nonceStr", nonceStr2);  
		finalpackage.put("package", packages);  
		finalpackage.put("signType", "MD5");
		String finalsign = reqHandler.createSign(finalpackage);
		
		map.put("productName", body);
		map.put("totalFee", WeixinPayUtil.convertMoney(finalmoney));
		map.put("orderid", orderNo);
		
		// appId
		map.put("appid", appid2);
		// timeStamp
		map.put("timeStamp", timestamp);
		// nonceStr
		map.put("nonceStr", nonceStr2);
		// package
		map.put("packageStr", packages);
		// sign
		map.put("paySign", finalsign);
		
		return map;
	}
	
	/**
	 * 通过code获取VerifyCode
	 * @param code
	 * @return
	 */
	public String getVerifyCodeByCode(String code){
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		String openid = weixinUtil.getOpenidByToken(weixinConfig.getAppId(), weixinConfig.getSecret(), code);
		String verifyCode = weixinUserService.generateOpenIdVerifyCode(openid);
		return verifyCode;
	}
	
	/**
	 * 分享连接获取config
	 * @return
	 */
	public Map<String,String> getWXConfig(String urlParam){
		HttpServletRequest request = ServletActionContext.getRequest();
		HttpServletResponse res = ServletActionContext.getResponse();
		WeixinConfig weixinConfig = weixinUtil.getWeixinConfig();
		String appid = weixinConfig.getAppId();
		AccessToken accessToken = weixinUtil.getAccessToken(appid, null, false);
		String jsapi_ticket = weixinUtil.getJsApiTicket(accessToken.getAccess_token());
		
		//String url = "http://www.360fangxun.com/static/ra/coupon/shareTest.html";
		//String url = weixinService.getUrlSiteName("ra") + "/coupon/userCoupon.addUserCoupon.html";
		String url = weixinService.getUrlSiteName("ra") + "/coupon/userCoupon.goInvitePage.html" + urlParam;
	
		Map<String, String> ret = new HashMap<String, String>();
        String nonce_str = create_nonce_str();
        String timestamp = create_timestamp();
        String string1;
        String signature = "";

        //注意这里参数名必须全部小写，且必须有序
        string1 = "jsapi_ticket=" + jsapi_ticket +
                  "&noncestr=" + nonce_str +
                  "&timestamp=" + timestamp +
                  "&url=" + url;
        System.out.println(string1);

        try
        {
            MessageDigest crypt = MessageDigest.getInstance("SHA-1");
            crypt.reset();
            crypt.update(string1.getBytes("UTF-8"));
            signature = byteToHex(crypt.digest());
        }
        catch (NoSuchAlgorithmException e)
        {
            e.printStackTrace();
        }
        catch (UnsupportedEncodingException e)
        {
            e.printStackTrace();
        }

        ret.put("url", url);
        ret.put("jsapi_ticket", jsapi_ticket);
        ret.put("noncestr", nonce_str);
        ret.put("timestamp", timestamp);
        ret.put("signature", signature);
        ret.put("appid", appid);
        
        return ret;
	}
	
    private static String byteToHex(final byte[] hash) {
        Formatter formatter = new Formatter();
        for (byte b : hash)
        {
            formatter.format("%02x", b);
        }
        String result = formatter.toString();
        formatter.close();
        return result;
    }

    private static String create_nonce_str() {
        return UUID.randomUUID().toString();
    }

    private static String create_timestamp() {
        return Long.toString(System.currentTimeMillis() / 1000);
    }
	
}
